package com.codingchili.instance.controller;

import com.codingchili.instance.context.GameContext;
import com.codingchili.instance.model.admin.AdminEvent;
import com.codingchili.instance.model.dialog.AdminEngine;
import com.codingchili.instance.transport.InstanceRequest;

import com.codingchili.core.logging.Level;
import com.codingchili.core.logging.Logger;
import com.codingchili.core.protocol.Api;
import com.codingchili.core.protocol.exception.AuthorizationRequiredException;

import static com.codingchili.common.Strings.*;

/**
 * @author Robin Duda
 * <p>
 * Handles admin functions.
 */
public class AdminHandler implements GameHandler {
    private static final String AUTHORIZED = "authorized";
    private static final String COMMAND = "admin.cmd";
    private final AdminEngine engine;
    private final GameContext game;
    private final Logger logger;

    public AdminHandler(GameContext game) {
        this.game = game;
        this.logger = game.getLogger(getClass());
        this.engine = new AdminEngine(game);
    }

    @Api
    public void admin(InstanceRequest request) {
        var authorized = game.instance().realm().isAdmin(request.account());
        var event = request.raw(AdminEvent.class);

        log(request, event, authorized);

        if (authorized) {
            engine.handle(event);
        } else {
            request.error(new AuthorizationRequiredException());
        }
    }

    private void log(InstanceRequest request, AdminEvent event, boolean authorized) {
        logger.event(COMMAND, (authorized) ? Level.INFO : Level.WARNING)
                .put(ID_ACCOUNT, request.account())
                .put(ID_CHARACTER, request.target())
                .put(ID_QUERY, String.format("'%s'", event.getLine()))
                .put(ID_ENTITY, event.getEntity())
                .put(AUTHORIZED, authorized)
                .send();
    }
}
